/*
 *Copyright (c) 2024 Black Sesame Technologies
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
*/

#include "../../common/RegBase.h"
#include "../../library/general_inc.h"
#include "../../library/utility_lite.h"
#include "../../common/IntNum.h"
#include "wdt.h"

/*==================================WDT DRV=====================================================*/
/*SET wdt enable.*/
void wdt_timer_enable(unsigned int reg_base)
{
	REG_BIT_SET32((reg_base + WDT_CR), BIT0);
}

/*SET wdt disable*/
void wdt_timer_disable(unsigned int reg_base)
{
	REG_BIT_CLEAR32((reg_base + WDT_CR), BIT0);
}

/*SET  Response mode.*/
void wdt_response_mod_set(unsigned int reg_base,WDT_RMODE_E rmode)
{
	(rmode == WDT_RMODE_RESET) ? (REG_BIT_CLEAR32((reg_base + WDT_CR), BIT1)) : 
		(REG_BIT_SET32((reg_base + WDT_CR), BIT1));
}

/*SET Reset Pulse length*/
void wdt_reset_pluse_set(unsigned int reg_base, WDT_RPL_E rpl)
{
	unsigned int val;

	val = REG32_READ(reg_base + WDT_CR);
	val &= ~(7 << 2);
	val |= (rpl << 2);
	REG32_WRITE(reg_base + WDT_CR, val);
}

/*Kick the dog*/
void wdt_kick_dog(unsigned int reg_base)
{
	REG32_WRITE(reg_base + WDT_CRR, WDT_KICK_MAGIC);
}

/*Set the timeout period*/
void wdt_timeout_set(unsigned int reg_base,Wdg_TimeOutType top)
{
	REG32_WRITE(reg_base + WDT_TORR, (top | (top << 4)));
	wdt_kick_dog(reg_base);
}

/*Clear the intterrupt stat*/
void wdt_clear_intr(unsigned int reg_base)
{
	unsigned int dummy;
	dummy = REG32_READ(reg_base + WDT_EOI);
}


/*==================================WDT TEST=====================================================*/










//test interrupt connect line 
volatile u32 wdt_flag = 0;
void irq_wdt (unsigned int reg_base){    
    unsigned int regval;
    u32 int_num;
    
    int_num = get_int_num_by_reg_base(reg_base);
	if(int_num != ISR_NUM_INVALID)
	{
		IRQ_DISABLE(int_num);
	}

	regval = REG32_READ(reg_base+WDT_STAT);
	wdt_flag = 1;

	printf_intr("\r\n");
    printf_intr("wdt irq triggered, reg_base: 0x%08x \r\n", reg_base);
	return; 
}







/*================================================== Core0 ==================================================*/
void sw_core0_wdt_init(void)
{
	wdt_timer_disable(WDT0_BASE_ADDR);
    wdg_reset_mask_ctrl(WDT0_BASE_ADDR, 0);
    wdt_timeout_set(WDT0_BASE_ADDR,0xF);
    wdt_reset_pluse_set(WDT0_BASE_ADDR,WDT_RPL_8_CYCLES);
    wdt_response_mod_set(WDT0_BASE_ADDR,WDT_RMODE_INTR);
    wdt_timer_enable(WDT0_BASE_ADDR);

	//IRQ_ENABLE(SW_INTR_WDT_INTR0);
}

void sw_core0_wdt_kick_dog(void)
{
	wdt_kick_dog(WDT0_BASE_ADDR);
}

/*================================================== Core1 ==================================================*/
void sw_core1_wdt_init(void)
{
	wdt_timer_disable(WDT1_BASE_ADDR);
    wdg_reset_mask_ctrl(WDT1_BASE_ADDR, 0);
    wdt_timeout_set(WDT1_BASE_ADDR,0xF);
    wdt_reset_pluse_set(WDT1_BASE_ADDR,WDT_RPL_128_CYCLES);
    wdt_response_mod_set(WDT1_BASE_ADDR,WDT_RMODE_INTR);
    wdt_timer_enable(WDT1_BASE_ADDR);

	IRQ_ENABLE(SW_INTR_WDT_INTR1);
}

void sw_core1_wdt_kick_dog(void)
{
	wdt_kick_dog(WDT1_BASE_ADDR);
}

/*================================================== Core2 ==================================================*/
void sw_core2_wdt_init(void)
{
	wdt_timer_disable(WDT2_BASE_ADDR);
    wdg_reset_mask_ctrl(WDT2_BASE_ADDR, 0);
    wdt_timeout_set(WDT2_BASE_ADDR,0xF);
    wdt_reset_pluse_set(WDT2_BASE_ADDR,WDT_RPL_128_CYCLES);
    wdt_response_mod_set(WDT2_BASE_ADDR,WDT_RMODE_INTR);
    wdt_timer_enable(WDT2_BASE_ADDR);

	IRQ_ENABLE(SW_INTR_WDT_INTR2);
}

void sw_core2_wdt_kick_dog(void)
{
	wdt_kick_dog(WDT2_BASE_ADDR);
}

